package com.ruoyi.system.basicInformation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.TViolationTypeTree;
import com.ruoyi.common.exception.BaseException;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.ruoyi.system.basicInformation.bo.TViolationTypeAddBo;
import com.ruoyi.system.basicInformation.bo.TViolationTypeQueryBo;
import com.ruoyi.system.basicInformation.bo.TViolationTypeEditBo;
import com.ruoyi.system.basicInformation.domain.TViolationType;
import com.ruoyi.system.basicInformation.mapper.TViolationTypeMapper;
import com.ruoyi.system.basicInformation.vo.TViolationTypeVo;
import com.ruoyi.system.basicInformation.service.ITViolationTypeService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 违法类型Service业务层处理
 *
 * @author ruoyi
 * @date 2021-06-01
 */
@Service
public class TViolationTypeServiceImpl extends ServiceImpl<TViolationTypeMapper, TViolationType> implements ITViolationTypeService {

    /**
     * 构建前端所需要下拉树结构
     *
     * @param menus 菜单列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildViolationTypeTreeSelect(List<TViolationTypeTree> menus) {
        List<TViolationTypeTree> menuTrees = buildViolationTypeTree(menus);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public List<TViolationTypeTree> buildViolationTypeTree(List<TViolationTypeTree> depts) {
        List<TViolationTypeTree> returnList = new ArrayList<TViolationTypeTree>();
        List<Long> tempList = new ArrayList<Long>();
        for (TViolationTypeTree dept : depts) {
            tempList.add(dept.getId());
        }
        for (Iterator<TViolationTypeTree> iterator = depts.iterator(); iterator.hasNext(); ) {
            TViolationTypeTree dept = (TViolationTypeTree) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }
    @Override
    public List<TViolationTypeTree> selectViolationTypeList(TViolationTypeTree dept) {
        return baseMapper.selectViolationTypeList(dept);
    }
    /**
     * 递归列表
     */
    private void recursionFn(List<TViolationTypeTree> list, TViolationTypeTree t) {
        // 得到子节点列表
        List<TViolationTypeTree> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TViolationTypeTree tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<TViolationTypeTree> getChildList(List<TViolationTypeTree> list, TViolationTypeTree t) {
        List<TViolationTypeTree> tlist = new ArrayList<TViolationTypeTree>();
        Iterator<TViolationTypeTree> it = list.iterator();
        while (it.hasNext()) {
            TViolationTypeTree n = (TViolationTypeTree) it.next();
            if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    private boolean hasChild(List<TViolationTypeTree> list, TViolationTypeTree t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    @Override
    public TViolationTypeVo queryById(Long id){
        TViolationType db = this.baseMapper.selectById(id);
        return BeanUtil.toBean(db, TViolationTypeVo.class);
    }

    @Override
    public List<TViolationTypeVo> queryList(TViolationTypeQueryBo bo) {
        LambdaQueryWrapper<TViolationType> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getName()), TViolationType::getName, bo.getName());
        return entity2Vo(this.list(lqw));
    }

    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<TViolationTypeVo> entity2Vo(Collection<TViolationType> collection) {
        List<TViolationTypeVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, TViolationTypeVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<TViolationType> page = (Page<TViolationType>)collection;
            Page<TViolationTypeVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param userName 用户名称
     * @return 结果
     */
    @Override
    public String checkUserNameUnique(String userName, int id) {
        LambdaQueryWrapper<TViolationType> lqw = Wrappers.lambdaQuery();
        if (id != 0)
            lqw.notIn(TViolationType::getId, id);
        lqw.eq(TViolationType::getName, userName);
        lqw.eq(TViolationType::getDelFlag, "0");
        lqw.last("limit 1");
        int count = count(lqw);
        if (count > 0) {
            return "1";
        }
        return "0";
    }

    @Override
    public Boolean insertByAddBo(TViolationTypeAddBo bo) {
        TViolationType add = BeanUtil.toBean(bo, TViolationType.class);
        validEntityBeforeSave(add,1);
        return this.save(add);
    }

    @Override
    public Boolean updateByEditBo(TViolationTypeEditBo bo) {
        TViolationType update = BeanUtil.toBean(bo, TViolationType.class);
        validEntityBeforeSave(update,2);
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TViolationType entity, int type){
        //TODO 做一些数据校验,如唯一约束
        QueryWrapper<TViolationType> lqw = new QueryWrapper<>();
        lqw.lambda().eq(TViolationType::getName, entity.getName());
        TViolationType tShip = this.baseMapper.selectOne(lqw);
        if (Validator.isNotNull(tShip)) {
            //type为1时为新增
            if (type == 1) {
                //TODO 做一些数据校验,如唯一约束
                throw new BaseException("重复名称！");
            } else {
                if (entity.getId().longValue() != tShip.getId().longValue()) {
                    //TODO 做一些数据校验,如唯一约束
                    throw new BaseException("重复名称！");
                }
            }
        }
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }
}
